<?php

/**
 * Rozsireni pro entitu modulu.
 *
 * @author David Dusek
 */
namespace CMS\Module\Models;

use Doctrine\ORM\EntityRepository;

class ModuleRepository extends EntityRepository {
    public static $UP = 1;
    public static $DOWN = 2;
    
    /**
     * Porovna moduly v databazi s nactenymi moduly z aplikace a pokud najde
     * v databazi modul, ktery nema protejsek v aplikaci tak ho z databaze
     * odstrani.
     * @param array $loadedModules Asociativni pole se jmneny modulu nactenych 
     * z aplikace.
     * @return mixed Vysledek provedeni dotazu. 
     */
    public function removeMissingModules($loadedModules) {
        $moduleArray = array();
        foreach ($loadedModules as $module) {
            $moduleArray[] = $module->getName();
        }
        $moduleString = implode("','", $moduleArray);
        $moduleString = "'" . $moduleString . "'";
        
        $qb = $this->_em->createQueryBuilder();
        $qb->delete("\CMS\Module\Models\Module", "m")
           ->where($qb->expr()->notIn("m.name", $moduleString));
        $query = $qb->getQuery();
        
        return $query->execute();
    }
    
    /**
     * Ziskani maximalni hodnoty poradi.
     * @return int Nejvyssi honota + 1 nebo 1 pokud neni zadny zaznam. 
     */
    public function getMaxOrder() {
        $qb = $this->_em->createQueryBuilder();
        $qb = $qb->select($qb->expr()->max('m.order'))
                 ->from("\CMS\Module\Models\Module", 'm');
                
        $result = $qb->getQuery()->getSingleResult();
        return isset($result[1]) ? $result[1] + 1 : 1;
    }
    
    /**
     * Presunuti modulu v poradi o jednu pozici nahoru nebo dolu.
     * @param Module $moduleToMove modul k presunuti
     * @param int $direction Smer presunu. Definovane konstanty UP a DOWN.
     */
    public function move(Module $moduleToMove, $direction) {
        $qb = $this->_em->createQueryBuilder();
        $module = null;
        
        if ($direction == self::$UP) {
            $qb = $qb->select("m")
                     ->from("\CMS\Module\Models\Module", 'm')
                     ->where("m.order < " . $moduleToMove->getOrder())
                     ->orderBy("m.order", "desc")
                     ->setMaxResults(1);
        } else {
            $qb = $qb->select("m")
                     ->from("\CMS\Module\Models\Module", 'm')
                     ->where("m.order > " . $moduleToMove->getOrder())
                     ->orderBy("m.order", "asc")
                     ->setMaxResults(1);
        }
        
        try {
            $module = $qb->getQuery()->getSingleResult();
        } catch (\Doctrine\ORM\NoResultException $e) {
            return;
        }
        
        // Pokud je kam posouvat tj. neni prvni pri posunu nahoru nebo posledni pri
        // posunu dolu.
        if ($module !== null) {
            $oldOrder = $module->getOrder();
            $module->setOrder($moduleToMove->getOrder());
            $moduleToMove->setOrder($oldOrder);
            $this->_em->flush();
        }
    }
}
